from dvadmin.utils.serializers import CustomModelSerializer
from rest_framework.decorators import action
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from dvadmin.utils.json_response import SuccessResponse, ErrorResponse, DetailResponse
from dvadmin.utils.viewset import CustomModelViewSet
from ops.devops.models import Domain, DomainSet
from ops.devops.utils import utils_domain
from ops.devops.utils.util_config import get_config
from ops.chatbot.utils.utils import get_kv_by_list


class DomainSerializer(CustomModelSerializer):
    """
    devops-序列化器
    """
    class Meta:
        model = Domain
        fields = '__all__'
        read_only_fields = ["id"]


class DomainSetSerializer(CustomModelSerializer):
    """
    devops-序列化器
    """
    class Meta:
        model = DomainSet
        fields = '__all__'
        read_only_fields = []


class DomainViewSet(CustomModelViewSet):
    """
    devops接口
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """
    exclude_field = []
    queryset = Domain.objects.all()
    serializer_class = DomainSerializer
    extra_filter_backends = []
    permission_classes = []
    search_fields = ["name", "status"]

    # 从云获取domain并更新到数据库中
    @swagger_auto_schema(request_body=openapi.Schema(
        type=openapi.TYPE_OBJECT
    ), operation_summary='拉取域名列表')
    @action(methods=['put'], detail=False)
    def pull_domain(self, request, *args, **kwargs):
        client = utils_domain.DomainOp.create_client()
        zones = utils_domain.DomainOp.list_zones(client)

        if not zones:
            msg = '域名列表拉取失败，请登录云控制台检查域名列表是否存在！'
            return ErrorResponse(code=400, msg=msg)
        for zone in zones:
            name = zone.name
            status = zone.status
            description = zone.description
            try:
                domain_tmp = Domain.objects.get(name=name)
                domain_tmp.status = status
                domain_tmp.description = description
                domain_tmp.save()
                print('域名已存在，更新域名中')
            except Domain.DoesNotExist:
                print('域名不存在，新增域名到表中')
                domain_info = {'name': name, 'status': status, 'description': description}
                obj = Domain(**domain_info)
                obj.save()
        return SuccessResponse(data="域名创建/更新成功")


class DomainSetViewSet(CustomModelViewSet):
    """
    devops接口
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """
    exclude_field = []
    queryset = DomainSet.objects.all()
    serializer_class = DomainSetSerializer
    extra_filter_backends = []
    permission_classes = []
    search_fields = ["domain", "status"]

    # 重写方法
    def create(self, request, *args, **kwargs):
        data = request.data

        # 获取配置
        conf = get_config('cloud')
        domain_root = conf.get('domain_root')
        domain_endpoint = conf.get('domain_endpoint')

        # 从传参中获取domain_type domain_type records
        domain_name = data.get('domain')
        domain_type = data.get('type')
        records = data.get('records')
        client = utils_domain.DomainOp.create_client()
        zones = utils_domain.DomainOp.list_zones(client)
        if not zones:
            print('获取endpoint={0}的区域失败，请检查'.format(domain_endpoint))
        name_id = get_kv_by_list(zones, 'name', 'id')
        zone_id = name_id.get(domain_root)
        print(zone_id)
        res = utils_domain.DomainOp.create_record_set(client, zone_id, domain_name, domain_type, records.split(','))

        # 域名添加时状态码不为200，默认失败
        if res.get('code') != 200:
            return ErrorResponse(msg=res.get('msg'))
        serializer = self.get_serializer(data=data, request=request)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)

        return DetailResponse(data=serializer.data, msg="新增成功")

    # 从云获取domain并更新到数据库中
    @swagger_auto_schema(request_body=openapi.Schema(
        type=openapi.TYPE_OBJECT
    ), operation_summary='获取解析记录')
    @action(methods=['PUT'], detail=False)
    def get_domain_sets(self, request, *args, **kwargs):
        client = utils_domain.DomainOp.create_client()
        recordsets = utils_domain.DomainOp.get_record_sets(client).get('recordsets')

        for recordset in recordsets:
            print(recordset)
            domain = recordset.name
            status = recordset.status
            type = recordset.type
            ttl = recordset.ttl
            records = recordset.records

            try:
                DomainSet_tmp = DomainSet.objects.get(domain=domain)
                DomainSet_tmp.status = status
                DomainSet_tmp.type = type
                DomainSet_tmp.ttl = ttl
                # 将records由list转换成str，以逗号隔开
                DomainSet_tmp.records = ','.join(records)
                DomainSet_tmp.save()
            except DomainSet.DoesNotExist:
                print('域名不存在，新增域名解析记录到表中')
                domain_info = {'domain': domain, 'status': status, 'type': type, 'ttl': ttl, 'records': ','.join(records)}
                obj = DomainSet(**domain_info)
                obj.save()
        return SuccessResponse(data="域名获取成功")
